#import "BWCrossStitchCircleTool.h"
#import "BWCrossStitchChangeList.h"

@implementation BWCrossStitchCircleTool

- (void) drawCircleFromRow: (int) row1   column: (int) column1
                     toRow: (int) row2   column: (int) column2
                withThread: (BWThread *) thread
{
    // invalidate old change list in view
    [changeList purge];

    int minRow = MIN (row1, row2);
    int maxRow = MAX (row1, row2);
    int minColumn = MIN (column1, column2);
    int maxColumn = MAX (column1, column2);

    // adapted from http://www.bsdg.org/SWAG/GRAPHICS/0276.PAS.html
    // mx, my, a, b are defining parameters
    int mx, my, a, b;
    mx = (maxColumn - minColumn) / 2;
    my = (maxRow - minRow) / 2;
    a = (maxColumn - minColumn) / 2;
    b = (maxRow - minRow) / 2;

    int x, mx1, mx2, my1, my2;
    long aq, bq, dx, dy, r, rx, ry;

    [changeList addStitchWithThread: thread 
                atRow: minRow + my
                column: minColumn + mx + a];
    [changeList addStitchWithThread: thread 
                atRow: minRow + my
                column: minColumn + mx - a];

    mx1 = mx - a;   my1 = my;
    mx2 = mx + a;   my2 = my;

    aq = a * a;
    bq = b * b;
    dx = aq << 1;
    dy = bq << 1;
    r  = a * bq;
    rx = r << 1;
    ry = 0; 
    x = a;

    while (x > 0) {
        if (r > 0) {
            my1++;  my2--;
            ry += dx;
            r -= ry;
        }
        if (r <= 0) {
            x--;
            mx1++;
            mx2--;
            rx -= dy;
            r += rx;
        }
        [changeList addStitchWithThread: thread 
                    atRow: minRow + my1
                    column: minColumn + mx1];
        [changeList addStitchWithThread: thread 
                    atRow: minRow + my2
                    column: minColumn + mx1];
        [changeList addStitchWithThread: thread 
                    atRow: minRow + my1
                    column: minColumn + mx2];
        [changeList addStitchWithThread: thread 
                    atRow: minRow + my2
                    column: minColumn + mx2];
    }

    [self invalidateRectAt: row1  column: column1
          row: row2  column: column2];

} // drawCircleFromRow


- (void) startDragAtRow: (int) row  
                 column: (int) column
                 thread: (BWThread *) thread
{
    startRow = endRow = row;
    startColumn = endColumn = column;

    [self drawCircleFromRow: startRow  column: startColumn
          toRow: endRow  column: endColumn
          withThread: thread];

} // startDragAtRow


- (void) continueDragAtRow: (int) row
                    column: (int) column
                    thread: (BWThread *) thread
{
    [self invalidateRectAt: startRow  column: startColumn
          row: endRow  column: endColumn];

    if ([self isConstrained]) {
        int rowDelta = abs(startRow - row);
        if (column < startColumn) {
            column = startColumn - rowDelta;
        } else {
            column = startColumn + rowDelta;
        }
    }

    endRow = row;
    endColumn = column;

    [self drawCircleFromRow: startRow  column: startColumn
          toRow: endRow  column: endColumn
        withThread: thread];

} // continueDragAtRow

- (NSString *) name
{
    return (@"Draw circles with cross stitches");
} // name

@end // BWCrossStitchCircleTool

